﻿using System;
using System.Collections.ObjectModel;
using Xenta.Operations;

namespace Xenta.Security
{
    /// <summary>
    /// Exposes the security rule interface.
    /// </summary>
    public interface ISecurityRule
    {
        #region Methods

        /// <summary>
        /// Checks, if the security rule is satisfied.
        /// </summary>
        /// <param name="ctx">The working context.</param>
        /// <param name="uow">The unit of work.</param>
        /// <returns>true if security rule is satisfied; otherwis false.</returns>
        bool DoesPass(IWorkingContext ctx, IUnitOfWork uow);

        #endregion
    }

    /// <summary>
    /// Represents the security rule, which uses the specific predicate.
    /// </summary>
    public class SecurityRule : ISecurityRule
    {
        #region Fields

        private readonly Func<IWorkingContext, IUnitOfWork, Boolean> _predicate;

        #endregion

        #region Ctors

        /// <summary>
        /// Initializes a new instance of the 
        /// </summary>
        /// <param name="predicate">The predicate function.</param>
        public SecurityRule(Func<IWorkingContext, IUnitOfWork, Boolean> predicate)
        {
            if(predicate == null)
                throw new ArgumentNullException("predicate");
            _predicate = predicate;
        }

        #endregion

        #region Methods

        /// <summary>
        /// Checks, if the security rule is satisfied.
        /// </summary>
        /// <param name="ctx">The working context.</param>
        /// <param name="uow">The unit of work.</param>
        /// <returns>true if security rule is satisfied; otherwis false.</returns>
        public bool DoesPass(IWorkingContext ctx, IUnitOfWork uow)
        {
            return _predicate(ctx, uow);
        }

        #endregion
    }

    /// <summary>
    /// Represents the collection of security rules.
    /// </summary>
    public class SecurityPolicy : Collection<ISecurityRule>
    {
    }
}
